#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = 'tyh'
__mtime__ = '18-10-9'
# code is far away from bugs with the god animal protecting ~
"""
import base64
import pickle
import re

from django.contrib.auth.backends import ModelBackend
from rest_framework_jwt.settings import api_settings
from django_redis import get_redis_connection

from users.models import User


def jwt_response_payload_handler(token, user=None, request=None):
    '''重写payload，用来在响应体中携带user_id和username'''
    return {
        'token': token,
        'user_id': user.id,
		'username': user.username
    }



class UsernameMobileAuthBackend(ModelBackend):
    '''重写authenticate方法，以便JWT在认证的时候可以用手机号码进行登陆'''

    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            if re.match(r'^1[3-9]\d{9}$', username):
                user = User.objects.get(mobile=username)
            else:
                user = User.objects.get(username=username)
        except Exception as e:
            user = None

        if user:
            user_is_validate = user.check_password(password)
            if user_is_validate:
                return user


# 生成jwt token
def generate_jwt_token(user):
    # 补充生成记录登录状态的token
    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)
    return token


# 合并购物车
def merge_cookie_cart(request, user, response):
    """
    从cookie中取出购物车信息，再写入到redis数据库中
    :param request:
    :param user:
    :param response:
    :return:
    """
    cookie = request.COOKIES.get('cart')
    if not cookie:
        return response

    skus_cookie = pickle.loads(base64.b64decode(cookie))

    cookie_cart = {}
    selected_list = []
    non_selected_list = []

    for sku_id, sku_dict in skus_cookie.items():
        cookie_cart[sku_id] = sku_dict['count']
        if sku_dict['selected']:
            selected_list.append(sku_id)
        else:
            non_selected_list.append(sku_id)

    if cookie_cart:
        redis = get_redis_connection('cart').pipeline()        # type:

        redis.hmset('cart_%s' % user.id, cookie_cart)
        if selected_list: redis.sadd('cart_selected_%s'% user.id, *selected_list)
        if non_selected_list: redis.srem('cart_selected_%s'% user.id, *non_selected_list)

        redis.execute()
        response.delete_cookie('cart')

    return response

